/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */
package com.yami.shop.api.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.app.dto.ProdCommDataDto;
import com.yami.shop.bean.app.dto.ProdCommDto;
import com.yami.shop.bean.app.dto.ProductDto;
import com.yami.shop.bean.app.dto.SkuDto;
import com.yami.shop.bean.app.vo.ProductVO;
import com.yami.shop.bean.enums.ProdStatusEnums;
import com.yami.shop.bean.enums.ProdType;
import com.yami.shop.bean.enums.ShopStatus;
import com.yami.shop.bean.event.LoadProdActivistEvent;
import com.yami.shop.bean.event.ProcessActivityProdPriceEvent;
import com.yami.shop.bean.model.ProdParameter;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.bean.model.Sku;
import com.yami.shop.bean.param.ProductParam;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.Json;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.delivery.common.model.SameCity;
import com.yami.shop.delivery.common.service.SameCityService;
import com.yami.shop.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author LGH
 */
@RestController
@RequestMapping("/prod")
@Api(tags = "商品接口")
public class ProdController {

    @Autowired
    private ProductService prodService;
    @Autowired
    private MapperFacade mapperFacade;
    @Autowired
    private SameCityService sameCityService;
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private SkuService skuService;
    @Autowired
    private ProdCommService prodCommService;
    @Autowired
    private ShopDetailService shopDetailService;
    @Autowired
    private ProdParameterService prodParameterService;


    @GetMapping("/prodInfo")
    @ApiOperation(value = "商品详情信息", notes = "根据商品ID（prodId）获取商品信息")
    @ApiImplicitParam(name = "prodId", value = "商品ID", required = true, dataType = "Long")
    public ServerResponseEntity<ProductVO> prodInfo(Long prodId) {
        Integer dbLang = I18nMessage.getDbLang();
        Product product = prodService.getProductInfo(prodId, dbLang);
        if (product == null || product.getStatus() != 1) {
            // 商品已下线
            throw new YamiShopBindException("yami.product.off.shelves");
        }
        // 检查店铺是否处于营业状态
        checkShopStatusIsOpen(product);
        // 启用的sku列表
        List<Sku> skuList = skuService.listPutOnSkuAndSkuStock(prodId, dbLang);
        product.setSkuList(skuList);
        ProductVO productVO = mapperFacade.map(product, ProductVO.class);
        // 如果是积分商品， 所有数据已经获取完成了
        if (Objects.equals(productVO.getProdType(), ProdType.PROD_TYPE_SCORE.value())) {
            return ServerResponseEntity.success(productVO);
        }
        // 发送事件，获取商品可用的正在开播直播间、商品套餐、秒杀、团购、积分商品信息
        applicationContext.publishEvent(new LoadProdActivistEvent(prodId, productVO, product.getProdType()));
        // 普通商品有多种物流，需要加载物流模板信息
        if (Objects.equals(productVO.getProdType(), ProdType.PROD_TYPE_NORMAL.value())) {
            loadDeliveryMode(product.getDeliveryMode(), productVO);
        }
        // 商品参数列表
        List<ProdParameter> prodParameters = prodParameterService.listParameter(prodId, I18nMessage.getDbLang());
        productVO.setProdParameterList(prodParameters);
        return ServerResponseEntity.success(productVO);
    }

    @GetMapping("/skuList")
    @ApiOperation(value = "sku信息", notes = "根据商品ID（prodId）单独获取sku信息")
    @ApiImplicitParam(name = "prodId", value = "商品ID", required = true, dataType = "Long")
    public ServerResponseEntity<List<SkuDto>> skuList(@RequestParam("prodId") Long prodId) {
        return ServerResponseEntity.success(skuService.getProdDetailSkuInfo(prodId));
    }

    @GetMapping("/isStatus")
    @ApiOperation(value = "校验商品是否下架", notes = "根据商品ID（prodId）校验商品是否下架")
    @ApiImplicitParam(name = "prodId", value = "商品ID", required = true)
    public ServerResponseEntity<Boolean> isStatus(Long prodId) {
        Product product = prodService.getProductByProdId(prodId, I18nMessage.getDbLang());
        if (product == null || product.getStatus() != 1) {
            return ServerResponseEntity.success(false);
        }
        return ServerResponseEntity.success(true);
    }

    @GetMapping("/listProdByIdsAndType")
    @ApiOperation(value = "获取商品信息", notes = "根据商品ids获取商品信息")
    public ServerResponseEntity<List<ProductDto>> listProdByIdsAndType(ProductParam product) {
        product.setLang(I18nMessage.getDbLang());
        product.setStatus(ProdStatusEnums.NORMAL.getValue());
        List<Product> products = prodService.listProdByIdsAndType(product);
        processActivityProdPrice(product, products);
        List<ProductDto> productDtos = mapperFacade.mapAsList(products, ProductDto.class);
        return ServerResponseEntity.success(productDtos);
    }

    /**
     * 处理下活动商品的价格
     *
     * @param product  筛选参数
     * @param products 商品列表
     */
    private void processActivityProdPrice(ProductParam product, List<Product> products) {
        Map<Integer, List<Product>> prodMap = products.stream().collect(Collectors.groupingBy(Product::getProdType));
        if (prodMap.containsKey(ProdType.PROD_TYPE_SECKILL.value())) {
            applicationContext.publishEvent(new ProcessActivityProdPriceEvent(product, prodMap.get(ProdType.PROD_TYPE_SECKILL.value())));
        }

        if (prodMap.containsKey(ProdType.PROD_TYPE_GROUP.value())) {
            applicationContext.publishEvent(new ProcessActivityProdPriceEvent(product, prodMap.get(ProdType.PROD_TYPE_GROUP.value())));
        }
    }

    @GetMapping("/prodCommData")
    @ApiOperation(value = "返回商品评论数据(好评率 好评数量 中评数 差评数)", notes = "根据商品id获取")
    @ApiImplicitParam(name = "prodId", value = "商品id", required = true, dataType = "Long")
    public ServerResponseEntity<ProdCommDataDto> getProdCommData(Long prodId) {
        return ServerResponseEntity.success(prodCommService.getProdCommDataByProdId(prodId));
    }

    @GetMapping("/prodCommPageByProd")
    @ApiOperation(value = "根据商品返回评论分页数据", notes = "传入商品id和页码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "prodId", value = "商品id", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "evaluate", value = "-1或null 全部，0好评 1中评 2差评 3有图", required = true, dataType = "Long"),
    })
    public ServerResponseEntity<IPage<ProdCommDto>> getProdCommPageByProdId(PageParam page, Long prodId, Integer evaluate) {
        return ServerResponseEntity.success(prodCommService.getProdCommDtoPageByProdId(page, prodId, evaluate));
    }

    private void checkShopStatusIsOpen(Product product) {
        // 积分商品的平台店铺不需要检验
        if (Objects.equals(product.getShopId(), Constant.PLATFORM_SHOP_ID)) {
            return;
        }
        Date now = new Date();
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(product.getShopId());
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value())) {
            return;
        }
        product.setShopName(shopDetail.getShopName());
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE.value()) || Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE_AUDIT.value())) {
            throw new YamiShopBindException("店铺已下线");
        }
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.STOP.value())) {
            if (now.compareTo(shopDetail.getContractStartTime()) < 0) {
                throw new YamiShopBindException("店铺未开始营业");
            } else {
                throw new YamiShopBindException("店铺已停止营业");
            }
        }
        throw new YamiShopBindException("店铺状态异常");
    }

    /**
     * 加载商品物流模板
     * @param deliveryMode
     * @param productVO
     */
    private void loadDeliveryMode(String deliveryMode, ProductVO productVO) {
        // 物流模板
        Product.DeliveryModeVO deliveryModeVO = Json.parseObject(deliveryMode, Product.DeliveryModeVO.class);
        SameCity sameCity = sameCityService.getSameCityByShopId(productVO.getShopId());
        // 如果同城配送是关闭了的，前端就不需要显示同城配送了
        if (Objects.isNull(sameCity) || !Objects.equals(1, sameCity.getStatus()) || Objects.isNull(deliveryModeVO.getHasCityDelivery())) {
            deliveryModeVO.setHasCityDelivery(false);
        }
        if (deliveryModeVO.getHasCityDelivery() != null && deliveryModeVO.getHasCityDelivery() && Objects.nonNull(sameCity)) {
            productVO.setStartDeliveryFee(sameCity.getStartingFee());
        }
        productVO.setDeliveryModeVO(deliveryModeVO);
    }

}
